package logger

import (
	"encoding/json"
	"fmt"
	"time"
	"unicode/utf8"
)

// PrintStarLine defalut length is 270
func PrintStarLine(length ...int) {
	c := 270
	if len(length) > 0 {
		c = length[0]
	}

	Printf(GetCharBy("*", c))
}

func GetCharBy(char string, length int) string {
	s := ""
	if length <= 0 {
		return s
	}

	for i := 0; i < length; i++ {
		s += char
	}

	return s
}

func PrintBr(count ...int) {
	c := 1
	if len(count) > 0 {
		c = count[0]
	}

	Printf(GetCharBy("\n", c))
}

// 只是打印错误，不会中断执行，后面的可以可以继续执行, 如果打印了错误返回true, 没有错误返回false, 可配合if 做return 逻辑
func ErrorfIfNotNil(err error) bool {
	if err == nil {
		return false
	}

	Errorf(err.Error())

	return true
}

// 打印错误，中止后面的代码执行
func PanicErrIfNotNil(err error) {
	if err == nil {
		return
	}

	Errorf(err.Error())
	panic(err)
}

func getMillisecond() int64 {
	return time.Now().UnixNano() / 1000000
}

type Cost struct {
	start int64
	end   int64
}

func Start() *Cost {
	return &Cost{start: getMillisecond()}
}

// 配合defer实现一行代码打印耗时 defer logger.Start().End()
func (c *Cost) End(str string) *Cost {
	c.end = getMillisecond()
	costTime := float64(c.end-c.start) / float64(1000)
	costMin := int(costTime / float64(time.Minute.Seconds()))
	costSec := int(costTime) % int(time.Minute.Seconds())
	InfofSkip(3, "%s 耗时: %s 秒, ( %s 分 %s 秒 )", str, Cyan(fmt.Sprintf("%.3f", costTime)), Cyan(fmt.Sprintf("%d", costMin)), Cyan(fmt.Sprintf("%d", costSec)))
	return c
}

func (c *Cost) Cost() int64 {
	c.end = getMillisecond()
	return c.end - c.start
}

// 如果v不为空，以可读的方式打印json对象
func PrintJsonIntent(v interface{}) {
	if v == nil {
		return
	}

	i, err := json.MarshalIndent(v, "", "  ")
	if err != nil {
		return
	}

	if len(i) > 0 {
		Infof(string(i[:]))
	}
}

func PadStart(s string, length int, pad ...string) string {
	if utf8.RuneCountInString(s) >= length {
		return s
	}

	p := " "
	if len(pad) > 0 {
		p = pad[0]
	}

	f := ""
	for i := 0; i < length-utf8.RuneCountInString(s); i++ {
		f += p
	}

	return f + s
}

func ElapsedTime(desc string) func() time.Duration {
	start := time.Now()
	return func() time.Duration {
		e := time.Since(start)
		// fmt.Printf("%s %v\n", desc, e)
		InfofSkip(3, "%s: %s", desc, Cyan(e.String()))
		return e
	}
}
